﻿/*
 * ©2009-2011 XELF
 * http://xelf.info
 */

#if XNA || WINDOWS_PHONE
using Microsoft.Xna.Framework;
#endif

namespace XELF.Framework {
#if XNA || WINDOWS_PHONE
	public static partial class MatrixHelper {
#else
	public partial struct Matrix {
#endif
		/// <summary>
		/// 回転クォータニオンから4行4列行列を作る。
		/// </summary>
		/// <param name="q"></param>
		/// <param name="m"></param>
		public static void CreateFromQuaternion(ref Quaternion q, out Matrix m) {
			Quaternion q0;
			Quaternion.Add(ref q, ref q, out q0);
			Quaternion q1 = new Quaternion(q0.X * q.X, q0.Y * q.Y, q0.Z * q.Z, q0.W * q.W);
			float xy = q0.X * q.Y;
			float wz = q0.W * q.Z;
			float xz = q0.X * q.Z;
			float wy = q0.W * q.Y;
			float yz = q0.Y * q.Z;
			float wx = q0.W * q.X;
			m = new Matrix();
			m.M11 = 1 - q1.Y - q1.Z;
			m.M12 = xy + wz;
			m.M13 = xz - wy;
			m.M21 = xy - wz;
			m.M22 = 1 - q1.X - q1.Z;
			m.M23 = yz + wx;
			m.M31 = xz + wy;
			m.M32 = yz - wx;
			m.M33 = 1 - q1.X - q1.Y;
			m.M14 = 0; m.M24 = 0; m.M34 = 0;
			m.M41 = 0; m.M42 = 0; m.M43 = 0; m.M44 = 1;
		}
	}
}

namespace XELF.Framework {
#if XNA || WINDOWS_PHONE
	public static partial class MatrixHelper {
#else
	public partial struct Matrix {
#endif
		/// <summary>
		/// クォータニオンの左積の行列表現を作る。
		/// </summary>
		/// <param name="value"></param>
		/// <param name="result"></param>
		public static void CreateQuaternionLeftMultiply(ref Quaternion value, out Matrix result) {
			result = new Matrix(
				+value.W, +value.Z, -value.Y, -value.X,
				-value.Z, +value.W, +value.X, -value.Y,
				+value.Y, -value.X, +value.W, -value.Z,
				+value.X, +value.Y, +value.Z, +value.W);
		}

		/// <summary>
		/// クォータニオンの右積の行列表現を作る。
		/// </summary>
		/// <param name="value"></param>
		/// <param name="result"></param>
		public static void CreateQuaternionRightMultiply(ref Quaternion value, out Matrix result) {
			result = new Matrix(
				+value.W, -value.Z, +value.Y, -value.X,
				+value.Z, +value.W, -value.X, -value.Y,
				-value.Y, +value.X, +value.W, -value.Z,
				+value.X, +value.Y, +value.Z, +value.W);
		}
	}

}
